﻿# -*- coding:utf-8 -*-
#
import os, datetime, string
from ftplib import FTP
#
from django.conf import settings
from django.shortcuts import render_to_response
from django.shortcuts import get_object_or_404
from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from django.contrib.auth.decorators import permission_required
from django.contrib import messages
from django.template import RequestContext, Context
from django.template.loader import render_to_string
from django.core.urlresolvers import reverse
from django.core.files.base import ContentFile
from django.core.files.uploadedfile import SimpleUploadedFile, InMemoryUploadedFile
from django.forms.models import model_to_dict, save_instance
#
from forms import AuthorItemForm, ItemForm, ItemEditForm, AuthorEditForm
from echo.models import Item, Author, Variables
from echo.utils import PutFTPConn, ExistFTPConn, DeleteFTPConn



@login_required
@permission_required('echo.add_item')
def echo_index(request):
    no_publish_items = Item.objects.filter(saved_ftp=False)
    if len(no_publish_items) > 0:
        if len(no_publish_items) == 1:
            messages.info(request, u'Найдены неопубликованные предметы! Сначала опубликуйте этот предмет.')
            return HttpResponseRedirect(reverse('result', args=[no_publish_items[0].id])) 
    
    new_author = False 
    if request.method == 'POST':
        # Проверяем добавление нового автора
        if request.POST['author'] == "":
            new_author = True
            form = AuthorItemForm(request.POST, request.FILES) 
        else:
            new_author = False
            form = ItemForm(request.POST, request.FILES) 
        if form.is_valid(): 
            author = form.cleaned_data['author'] 
            if author == None:
                author = Author(
                    first_name = form.cleaned_data['first_name'],
                    middle_name = form.cleaned_data['middle_name'],
                    surname = form.cleaned_data['surname'],
                    bio = form.cleaned_data['bio'],
                    person_photo = request.FILES['person_photo'],
                    user = request.user,)
                # проверка существования тезки    
                if len(Author.objects.filter(first_name=author.first_name,middle_name=author.middle_name, surname=author.surname)) > 0:
                    messages.warning(request, u'Автор с ФИО "%s" уже существует.' % author)  
                    return HttpResponseRedirect(reverse('echo_index', args=[])) 
                author.save()
                
            item = Item(
                author=author,
                item_title=form.cleaned_data['item_title'],
                item_fulltitle=form.cleaned_data['item_fulltitle'],
                description=form.cleaned_data['description'],
                item_photo= request.FILES['item_photo'], 
                publ_date = form.cleaned_data['publ_date'],
                user = request.user,)
            if len(Item.objects.filter(item_title=item.item_title, author=item.author)) > 0:    
                messages.warning(request, u'Предмет с названием "%s" уже существует.' % item)  
                return HttpResponseRedirect(reverse('echo_index', args=[])) 
            item.save()

            # запись в шаблон XML предмета происходит в Result
            return HttpResponseRedirect(reverse('result', args=[item.id])) 
    else:
        form = AuthorItemForm()
        
    context = Context({
        'form' : form,
        'new_author':new_author,
    })
    return render_to_response('echo_index.html', context,  context_instance=RequestContext(request, processors=[]))


@login_required
@permission_required('echo.add_item')
def data_edit(request, item_id):
    ''' Обработка и сохранение результатов изменений автора и предмета '''
    item = get_object_or_404(Item, id = item_id)
    item_author_data = model_to_dict(item)
    item_author_data.update(model_to_dict(item.author))   
    new_author = True
    if request.method == 'POST':
        form = AuthorItemForm(request.POST, request.FILES, initial=item_author_data)
        if form.is_valid(): 
            item.saved_ftp = False 
            item.author.saved_ftp = False
            save_instance(form, item.author)
            save_instance(form, item)
            messages.success(request, u'Свойства успешно изменены.')
            return HttpResponseRedirect(reverse('result', args=[item.id]))               
    else:
        form = AuthorItemForm(initial=item_author_data)
    context = Context({
        'form' : form,
        'edit_form':True,
        'item':item,
    })
    return render_to_response('echo_index.html', context,  context_instance=RequestContext(request, processors=[]))
    
    
    

@login_required
@permission_required('echo.add_item')
def result(request, item_id):
    ''' Генерация XML и показ результатов '''
    item = get_object_or_404(Item, id = item_id)
    #author = get_object_or_404(Author, id = item.author.id)
    #if not item.saved_ftp:
    # Запись в шаблон XML предмета
    item_xml = render_to_string('xml_item.xml', {
        'id' : item.id,
        'author' : item.author.id,  
        'item_title': item.item_title,
        'item_fulltitle': item.item_fulltitle,
        'item_photo': os.path.basename(item.preview_item_photo()),
        'item_photo_s': os.path.basename(item.preview_item_photo_small()),
        'description': item.description,
        'year' : item.publ_date.year,
        'month' : item.publ_date.month,
        'day' : item.publ_date.day,
        'hours' : item.publ_date.hour,
        'minutes' : item.publ_date.minute,})
    try:
        result_file = open('%s%s.xml' % (settings.ECHO_ITEM_PATH, item.id), 'w')
    except IOError, err:
        print err.strerror                                                                                        
    result_file.write(item_xml.encode('utf-8'))
    item.xml_file = result_file.name
    result_file.close()
    item.save()
    # Запись в шаблон XML автора
    author_xml = render_to_string('xml_author.xml', {
        'id' : item.author.id,
        'surname' : item.author.surname,
        'first_name' : item.author.first_name,
        'middle_name' : item.author.middle_name,
        'bio' : item.author.bio,
        'person_photo' : os.path.basename(item.author.preview_person_photo()),
        'person_photo_s' : os.path.basename(item.author.preview_person_photo_small()),
        'item' : item.id,})
    try:
        result_file = open('%s%s.xml' % (settings.ECHO_AUTHOR_PATH, item.author.id), 'w')
    except IOError, err:
        print err.strerror                                                                                        
    result_file.write(author_xml.encode('utf-8'))
    item.author.xml_file = result_file.name
    result_file.close()
    item.author.save()       
    
    
    context = Context({
        'item' : item,
        'item_xml_path': '%s%s' % (settings.ECHO_MEDIA_ITEM_PATH, os.path.split(item.xml_file)[1]),
        'author_xml_path': '%s%s' % (settings.ECHO_MEDIA_AUTHOR_PATH, os.path.split(item.author.xml_file)[1]),
    })
    return render_to_response('echo_result.html', context,  context_instance=RequestContext(request, processors=[])) 



@login_required
@permission_required('echo.add_item')    
def publish_ftp(request, item_id):
    ''' Публикация файлов XML и картинок на ftp ''' 
    item = get_object_or_404(Item, id = item_id) 
    if item.saved_ftp:
        messages.warning(request, u'Экспонат и (или) автор уже опубликованы.')
        return HttpResponseRedirect(reverse('result', args=[item.id]))          
    new_author = not item.author.saved_ftp
    # присвоение значений переменным
    variables = Variables.objects.all()
    var = dict((i.name, i.value) for i in variables)
    try:
        FTP_USER = var['ftp_user']
        FTP_PASS = var['ftp_pass']
        FTP_HOST = var['ftp_host']
        ITEM_FTP_DIR = var['ftp_item_dir']
        IMAGE_FTP_DIR = var['ftp_image_dir']
        AUTHOR_FTP_DIR = var['ftp_author_dir']
        DELETE_LOG_FILES = var['ftp_delete_log_files'].split(';')
    except:
        messages.warning(request, u'Приложение не настроено! Задайте значения переменным.')
        return HttpResponseRedirect(reverse('result', args=[item.id]))     
   
    # соединение с ФТП
    try:
        connection = FTP(FTP_HOST)
        connection.login(FTP_USER, FTP_PASS)
    except:
        messages.warning(request, u'Нет соединения с FTP сервером %s' % FTP_HOST)
        return HttpResponseRedirect(reverse('result', args=[item.id])) 
    
    author_filedata = ()
    if new_author:
        author_filedata = (
        (settings.ECHO_AUTHOR_PATH, item.author.xml_file,                      AUTHOR_FTP_DIR, False),
        (settings.ECHO_IMAGE_PATH,  item.author.preview_person_photo(),        IMAGE_FTP_DIR, False),
        (settings.ECHO_IMAGE_PATH,  item.author.preview_person_photo_small(),  IMAGE_FTP_DIR, False),)    
 
    filedata = (
        (settings.ECHO_ITEM_PATH,   item.xml_file,                             ITEM_FTP_DIR, False),#True
        (settings.ECHO_IMAGE_PATH,  item.preview_item_photo(),                 IMAGE_FTP_DIR, False),
        (settings.ECHO_IMAGE_PATH,  item.preview_item_photo_small(),           IMAGE_FTP_DIR, False),)  + author_filedata  
        
    for fd in  filedata:
        local_path = fd[0]
        local_file = os.path.split(fd[1])[1]  
        #if ExistFTPConn(connection, local_file, fd[2]): 
        #    if fd[3]:
        #        messages.warning(request, u'ОШИБКА! Файл  %s уже существует!' % local_file)
        #        return HttpResponseRedirect(reverse('result', args=[item.id]))         
        #    else:   
        #        pass
        #else:
        if PutFTPConn(connection, local_path, local_file, fd[2]):
            messages.warning(request, u'ОШИБКА! Файл  %s не был опубликован!' % local_file)
            return HttpResponseRedirect(reverse('result', args=[item.id]))    
    
    # удаление логов
    dir = '/log'
    for file in DELETE_LOG_FILES   :
        if DeleteFTPConn(connection, file, dir):
            messages.warning(request, u'ОШИБКА! Файл  %s/%s не удален!' % (dir, file))

    connection.quit() 
    
    # Успешная публикация.
    if new_author:
        item.author.saved_ftp = True
        item.author.save()
    item.saved_ftp = True
    item.save() 
 
    context = Context({
    })    
    return render_to_response('echo_publish_ftp.html', context,  context_instance=RequestContext(request, processors=[])) 
       
       
       
       

@login_required
@permission_required('echo.add_item')         
def items_list(request):
    '''Выводит список предметов из базы'''
    items_list = Item.objects.all()
    context = Context({
    'items_list':items_list,
    })    
    return render_to_response('echo_items_list.html', context, context_instance=RequestContext(request, processors=[]))



@login_required
@permission_required('echo.add_item')         
def authors_list(request):
    '''Выводит список авторов из базы'''
    authors_list = Author.objects.all()
    context = Context({
    'authors_list':authors_list,
    })    
    return render_to_response('echo_authors_list.html', context, context_instance=RequestContext(request, processors=[])) 
       
       
       
@login_required
@permission_required('echo.add_item')         
def edit_item(request, item_id): 
    '''Редактирование свойств предмета'''
    item_instance = get_object_or_404(Item, id = item_id)
    if item_instance.saved_ftp:
        messages.warning(request, u'Изменить данные опубликованного на сайте экспоната невозможно.')
        return HttpResponseRedirect(reverse('result', args=[item_instance.id]))      
    if request.method == 'POST':
        form = ItemEditForm(request.POST, request.FILES, instance=item_instance)
        if form.is_valid(): 
            item=form.save(commit=False)
            item.save()
            messages.success(request, u'Свойства предмета успешно изменены.')
            return HttpResponseRedirect(reverse('result', args=[item.id]))               
    else:
        form = ItemEditForm(instance=item_instance)
    context = Context({
    'form':form,
    'item':item_instance,
    })       
    return render_to_response('echo_edit_item.html', context, context_instance=RequestContext(request, processors=[])) 
       


@login_required
@permission_required('echo.add_item')         
def edit_author(request, author_id, item_id): 
    '''Редактирование свойств автора'''
    author_instance = get_object_or_404(Author, id = author_id)
    item_instance = get_object_or_404(Item, id = item_id)
    if author_instance.saved_ftp:
        messages.warning(request, u'Изменить данные опубликованного на сайте автора невозможно.')
        return HttpResponseRedirect(reverse('result', args=[item_instance.id]))       
    if request.method == 'POST':
        form = AuthorEditForm(request.POST, request.FILES, instance=author_instance)
        if form.is_valid(): 
            author=form.save(commit=False)
            author.save()
            messages.success(request, u'Свойства автора успешно изменены.')
            return HttpResponseRedirect(reverse('result', args=[item_instance.id]))               
    else:
        form = AuthorEditForm(instance=author_instance)
    context = Context({
    'form':form,
    'item':item_instance,
    })       
    return render_to_response('echo_edit_author.html', context, context_instance=RequestContext(request, processors=[]))        
       
       
       
       
       